package com.songlanyun.modules.group.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.songlanyun.common.drive.Validator;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.exception.GoodsExceptionEnum;
import com.songlanyun.modules.goods.model.values.GoodsSkuTableItem;
import com.songlanyun.modules.group.dao.ProductGoodsGroupDao;
import com.songlanyun.modules.group.entity.ProductGoodsGroupEntity;
import com.songlanyun.modules.group.model.vo.GoodsGroupSlim;
import com.songlanyun.modules.group.service.ProductGoodsGroupService;
import com.songlanyun.modules.shop.service.ShopService;
import com.songlanyun.modules.shop.service.impl.ShopServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.io.IOException;
import java.sql.Time;
import java.util.*;

/**
 * 商家店铺中的商品分组
 */
@Service("productGoodsGroupService")
public class ProductGoodsGroupServiceImpl extends ServiceImpl<ProductGoodsGroupDao, ProductGoodsGroupEntity> implements ProductGoodsGroupService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private ShopService shopService;
    /**
     * 根据商品分组实例来创建商品分组
     * @param entity
     * @return
     */
    @Override
    public ProductGoodsGroupEntity create(ProductGoodsGroupEntity entity) {
        ValidatorUtils.validateEntity(entity,AddGroup.class);
        validateNameExists(entity);
        validateParent(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    /**
     * 根据商品分组实例来修改商品分组
     * @param entity
     * @return
     */
    @Override
    public ProductGoodsGroupEntity modify(ProductGoodsGroupEntity entity) {
        ValidatorUtils.validateEntity(entity,UpdateGroup.class);
        validateExists(entity.getId());
        validateNameExists(entity);
        validateUpdateParentSafe(entity);

        this.baseMapper.updateById(entity);
        return this.getById(entity.getId());
    }

    /**
     * 根据商品分组标识删除商品分组
     * @param id
     * @return
     */
    @Override
    public void remove(Long id) {
        validateRemoveSafe(id);
        this.removeById(id);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ProductGoodsGroupEntity> page = this.page(
                new Query<ProductGoodsGroupEntity>().getPage(params),
                new QueryWrapper<ProductGoodsGroupEntity>()
        );

        return new PageUtils(page);
    }


    private List<Map<String, Object>> makeGoodsGroupTree(List<ProductGoodsGroupEntity> groups, long parentId) {
        List<Map<String, Object>> list = new ArrayList<>();

        for (ProductGoodsGroupEntity group : groups) {
            if (group.getParentId() == parentId) {
                Map<String, Object> map = new LinkedHashMap<>();
                map.put("id", group.getId());
                map.put("name", group.getName());
                map.put("parent_id", group.getParentId());
                map.put("order_index", group.getOrderIndex());
                map.put("shop_id", group.getShopId());
                map.put("cover_image", group.getCoverImage());
                map.put("children", makeGoodsGroupTree(groups, group.getId()));
                list.add(map);
            }
        }

        list.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                if ((int) o1.get("order_index") <= (int) o2.get("order_index")) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });

        return list;
    }

    /**
     * 查询商家创建的所有商品分组
     * @param shopId
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllGoodsGroup(Long shopId) {
        QueryWrapper<ProductGoodsGroupEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopId);
        List<ProductGoodsGroupEntity> list = this.list(queryWrapper);

        List<Map<String, Object>> data =  makeGoodsGroupTree(list, 0L);
        return data;
    }


    /**
     * 查询商家创建的某个分组的子分组
     * @param shopId
     * @param parentId
     * @return
     */
    @Override
    public List<ProductGoodsGroupEntity> getChildren(Long shopId, Long parentId) {
        QueryWrapper<ProductGoodsGroupEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",parentId);
        queryWrapper.eq("shop_id",shopId);
        List<ProductGoodsGroupEntity> entities = this.baseMapper.selectList(queryWrapper);
        return entities;
    }


    /**
     * 查询商家创建的某个分组的子分组
     * @param parentId
     * @return
     */
    @Override
    public List<ProductGoodsGroupEntity> getChildren(Long parentId) {
        QueryWrapper<ProductGoodsGroupEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",parentId);
        List<ProductGoodsGroupEntity> entities = this.baseMapper.selectList(queryWrapper);
        return entities;
    }

    /**
     * 查询商家创建的一级商品分组
     * @param shopId
     * @return
     */
    @Override
    public List<ProductGoodsGroupEntity> getFirstProductGoods(Long shopId) {
        shopService.loadShopBy(shopId,true);
        return this.getChildren(shopId,0L);
    }


    /**
     * 查询商家创建的某个商品分组
     * @param shopId
     * @param id
     * @return
     */
    @Override
    public ProductGoodsGroupEntity getByShopIdAndId(Long shopId, Long id) {

        ProductGoodsGroupEntity entity = this.baseMapper.getByShopIdAndId(shopId, id);
        return entity;
    }

    /**
     * 商家创建商品分组
     * @param shopId
     * @param entity
     * @return
     */
    @Override
    //@CacheEvict(value="goodsGroup", key="#shopId")
    @Transactional
    public ProductGoodsGroupEntity add(Long shopId, ProductGoodsGroupEntity entity) {

        shopService.loadShopBy(shopId,true);
        entity.setShopId(shopId);
        // redisTemplate.delete("shop:goodsGroup:"+shopId);       手动缓存
        return this.create(entity);
    }

    /**
     * 商家修改商品分组
     * @param shopId
     * @param entity
     * @return
     */
    @Override
    //@CacheEvict(value="goodsGroup", key="#shopId")
    @Transactional
    public ProductGoodsGroupEntity update(Long shopId, ProductGoodsGroupEntity entity) {
        shopService.loadShopBy(shopId,true);
        ProductGoodsGroupEntity load = this.getById(entity.getId());
        if(load!=null&& !load.getShopId().equals(shopId))
        {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SHOP_SAFE);
        }
        entity.setShopId(shopId);
        //        手动缓存  redisTemplate.delete("shop:goodsGroup:"+shopId);
        return this.modify(entity);
    }


    /**
     * 删除分组时的安全验证
     * 要删除的分组不存在不能删除
     * 下面还有子分组的不能删除
     * @param id
     */
    private void validateRemoveSafe(Long id) {
        ProductGoodsGroupEntity entity = this.getById(id);
        if (entity == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_NOT_EXISTS);
        }

        if(entity.loadChildren().size()>0)
        {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_REMOVE_SAFE);
        }
    }

    /**
     * 商家删除商品分组
     * @param shopId
     * @param id
     * @return
     */
    @Override
    @Transactional
    public void deleteByShopIdAndId(Long shopId, Long id) {
        shopService.loadShopBy(shopId,true);
        ProductGoodsGroupEntity load = this.getById(id);
        if(load!=null&& !load.getShopId().equals(shopId))
        {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SHOP_SAFE);
        }
        this.remove(id);
    }

    @Override
    public List<GoodsGroupSlim> selectGoodsGroupRelation(Long goodsAuthShopId) {
        return this.baseMapper.selectGoodsGroupRelation(goodsAuthShopId);
    }

    @Override
    public List<GoodsGroupSlim> selectGoodsGroupRelationByGoodsIdAndShopId(Long shopId, Long goodsId) {
        return this.baseMapper.selectGoodsGroupRelationByGoodsIdAndShopId(shopId,goodsId);
    }

    /**
     * 验证商品分组是否存在
     *
     * @param id
     */
    private void validateExists(Long id) {
        ProductGoodsGroupEntity entity = this.getById(id);
        if (entity == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_NAME_REPEAT);
        }
    }


    /**
     * 验证商品分组的名称不能重复
     *
     * @param entity
     */
    private void validateNameExists(ProductGoodsGroupEntity entity) {
        ProductGoodsGroupEntity target = this.getOne(new LambdaQueryWrapper<ProductGoodsGroupEntity>()
                .eq(ProductGoodsGroupEntity::getShopId,entity.getShopId())
                .eq(ProductGoodsGroupEntity::getParentId,entity.getParentId())
                .eq(ProductGoodsGroupEntity::getName,entity.getName())
                .last("limit 1"));

        if (target != null && !target.equals(entity)) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_NAME_REPEAT);
        }
    }

    /**
     * 如果新增时设置的父级对象不存在报错,
     * 如果新增加选择的父级是二级报错，只能有两级分组
     * @param entity
     */
    private void validateParent(ProductGoodsGroupEntity entity) {
        if(entity.getParentId()==null)
        {
            entity.setParentId(0L);
        }
        if(entity.getParentId()==0L) return ;
        ProductGoodsGroupEntity parent = this.baseMapper.getByShopIdAndId(entity.getShopId(),entity.getParentId());
        if (parent == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_PARENT_NOT_EXISTS);
        }

        if (parent.getParentId() > 0) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SECOND_SAFE);
        }
    }

    /**
     * 1、商品分组的父级不存在报错
     * 2、商品分组的父级还有父级报错
     * 3、自己有父级，同时自己还有下级分组报错，系统只需要两级
     * @param entity
     */
    private void  validateUpdateParentSafe(ProductGoodsGroupEntity entity)
    {
        if(entity.getParentId()>0)
        {
            //如果自己还有下级，说明现在成了三级，但是系统只需要两级，所以要报错

            ProductGoodsGroupEntity parent = this.baseMapper.getByShopIdAndId(entity.getShopId(),entity.getParentId());
            if(parent==null)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_PARENT_NOT_EXISTS);
            }


            if(parent.getParentId()>0)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SECOND_SAFE);
            }

            if(entity.getParentId().equals(entity.getId()))
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SELECT_SELF);
            }

            if(entity.loadChildren().size()>0)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_GROUP_SECOND_SAFE);
            }


        }
    }

}
